package com.boot.controller;


import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.boot.common.AlipayConfig;
import com.boot.pojo.tables.records.HdjPayRecord;
import com.boot.pojo.tables.records.HdjUserRecord;
import com.boot.until.UtilBase;
import lombok.extern.slf4j.Slf4j;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static com.boot.pojo.Tables.*;


@RestController
@RequestMapping("pay")
@Slf4j
public class PayController {

    @Autowired
    private DSLContext create;


    /**
     * 支付
     * @param request
     * @param response
     * @param money
     * @param count
     * @param userId
     * @throws Exception
     */
    @RequestMapping(value = "/add")
    @Transactional
    public void addOrder(HttpServletRequest request, HttpServletResponse response,String money,Integer count,Integer userId) throws Exception{
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient ( AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        //生成订单(pay)
        HdjPayRecord pay=create.newRecord(HDJ_PAY);
        pay.setOrderNum( UtilBase.getUUID().toUpperCase());
        pay.setCreateTime( UtilBase.getCurrentTime());
        pay.setMoney(new BigDecimal (money));
        pay.setVipCount (count );
        pay.setUserId(userId);
        //根据count判断会员属性
        String info="";
        if (count==31){
            info="会员月卡";
        }else if (count==186){
            info="会员半年卡";
        }else{
            info="会员年卡";
        }
        pay.setState(info);
        pay.insert();
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = pay.getOrderNum();
        //付款金额，必填
        String total_amount = pay.getMoney().toString();
        //订单名称，必填
        String subject = pay.getState();
        //商品描述，可空
        String body = "后端军产品";

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求
        String result = null;

            result = alipayClient.pageExecute(alipayRequest).getBody();

        response.setContentType("text/html;charset=" + AlipayConfig.charset);
            response.getWriter().write(result);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
    }


    @RequestMapping(value = "/notify")
    @Transactional
    public void notify_to (HttpServletRequest req,
                           HttpServletResponse rep) throws Exception{
        Map<String, String> params = new HashMap<> ();
        Map<String, String[]> requestParams = req.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        log.info("signVerified={}", signVerified);
        //——请在这里编写您的程序（以下代码仅作参考）——

                /* 实际验证过程建议商户务必添加以下校验：
                1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
                2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
                3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）
                4、验证app_id是否为该商户本身。
                */
        if (signVerified) {//验证成功
            //商户订单号
            String out_trade_no = new String(req.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            log.info("out_trade_no={}", out_trade_no);
            //支付宝交易号
            String trade_no = new String(req.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            log.info("trade_no={}", trade_no);
            //交易状态
            String total_amount=new String(req.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            //修改订单的状态
            HdjPayRecord pay = create.select()
                    .from(HDJ_PAY)
                    .where(HDJ_PAY.ORDER_NUM.eq(out_trade_no))
                    .fetchOne()
                    .into(HdjPayRecord.class);
            pay.setId(pay.getId());
            pay.setAliNum(trade_no);
            pay.setStatus(2);
            pay.setPayTime( UtilBase.getCurrentTime());
            pay.update();
            //维护会员信息
            HdjUserRecord user=create.select (  )
                    .from ( HDJ_USER )
                    .where ( HDJ_USER.ID.eq ( pay.getUserId () ) )
                    .fetchOne ()
                    .into ( HdjUserRecord.class );
            Integer count=pay.getVipCount ();
            //计算时间
            BigDecimal bigDecimal = new BigDecimal(count);
            BigDecimal bigDecimal2 = new BigDecimal(24);
            BigDecimal bigDecimal3 = new BigDecimal(60);
            BigDecimal bigDecimal4 = new BigDecimal(60);
            BigDecimal bigDecimal5 = new BigDecimal(1000);
            BigDecimal multiply = bigDecimal.multiply(bigDecimal2).multiply ( bigDecimal3 )
                    .multiply (bigDecimal4  ).multiply ( bigDecimal5 );
            long day=multiply.longValue ();
            log.info ( "需要增加的时间={}",day );
            Long datedTime=(day+System.currentTimeMillis ())/1000;
            log.info ( "最终时间",datedTime );
            //判断是增加还是重置
            if (user.getVipDated ()==null||(user.getVipDated ()< UtilBase.getCurrentTime ())){
                user.setIsVip ( 2 );
                user.setVipDated ( datedTime );
            }else {
                user.setIsVip ( 2 );
                user.setVipDated ( (user.getVipDated ()*1000+day)/1000 );
            }
            user.update ();
            /*if (trade_status.equals("TRADE_FINISHED")) {
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
            //如果有做过处理，不执行商户的业务程序

            //注意：
            //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
        } else if (trade_status.equals("TRADE_SUCCESS")) {
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
            //如果有做过处理，不执行商户的业务程序

            //注意：
            //付款完成后，支付宝系统发送该交易状态通知
        }*/
            req.setAttribute ( "order", trade_no);
            req.setAttribute ( "money",total_amount );
    }
            //存值

            //返回页面
        RequestDispatcher dispatcher=req.getRequestDispatcher ( "/WEB-INF/success.jsp" );
        dispatcher.forward ( req,rep );
    }


}
